'''
@Description: In User Settings Edit
@Author: your name
@Date: 2019-09-25 09:48:29
@LastEditTime: 2019-09-25 09:48:29
@LastEditors: your name
'''
from server.pao_python.pao.data import process_db
from ...service.app.my_order import OrderStatus, RecordStatus
from ...service.mongo_bill_service import MongoBillFilter
from ...service.buss_pub.bill_manage import BillManageService, OperationType, Status, TypeId
from ...service.common import get_info, get_current_user_id, execute_python, get_serial_number, SerialNumberType, get_current_organization_id
from server.pao_python.pao.data import string_to_date, date_to_string, get_cur_time, get_first_last_day_month, get_string_to_date
from server.pao_python.pao.service.data.mongo_db import MongoService, MongoFilter, C, N, F, as_date
import pandas as pd
import uuid
import copy
import datetime
from enum import Enum
from ...service.buss_mis.service_operation import ServiceOperationService
from ...service.app.confirm_order import ComfirmOrderService
from ...pao_python.pao.remote import JsonRpc2Error

'''
@Description: In User Settings Edit
@Author: your name
@Date: 2019-09-25 09:48:29
@LastEditTime: 2019-09-25 09:48:29
@LastEditors: your name
'''
'''
版权：Copyright (c) 2019 China

创建日期：Monday August 26th 2019
创建者：ymq(ymq) - <<email>>

修改日期: Monday, 26th August 2019 6:16:48 pm
修改者: ymq(ymq) - <<email>>

说明
 1、部分住宿过程（仅包括：入住、调房、请假、销假的过程）
'''


class CheckInStatus(Enum):
    '''入住记录表中状态的枚举值'''
    check_in = '居住中'
    retreat = '退住'


class AccommodationProcess(MongoService):
    '''住宿过程'''

    def __init__(self, db_addr, db_port, db_name, db_user, db_pwd, inital_password, session):
        self.db_addr = db_addr
        self.db_port = db_port
        self.db_name = db_name
        self.db_user = db_user
        self.db_pwd = db_pwd
        self.inital_password = inital_password
        self.session = session
        self.bill_manage_server = BillManageService(
            self.db_addr, self.db_port, self.db_name, self.db_user, self.db_pwd, self.inital_password, self.session)
        self.service_operation_func = ServiceOperationService(
            db_addr, db_port, db_name, db_user, db_pwd, inital_password, session)
        self.confirm_order_func = ComfirmOrderService(
            db_addr, db_port, db_name, db_user, db_pwd, inital_password, session)

    def check_in_process(self, data):
        '''入住过程：包括绑定床位PT_Bed、生成入住记录PT_Accommodation_Record、生成服务订单PT_Service_Order、生成住宿记录IEC_Chect_In
        Args :
        data：包括字段bed_id,checkin_date,enter_id,enter_operate_personnel_id,enter_record_reason_id,residents_id,enter_remark
        备注：生成的服务订单为选择的床位绑定的服务项目
        '''
        res = 'Fail'
        insert_bed = {'id': data['bed_id'],
                      'residents_id': data['residents_id']}
        # 查找床位绑定的服务包id
        _filter = MongoBillFilter()
        _filter.match_bill(C('id') == data['bed_id'])\
               .inner_join_bill('PT_Service_Item_Package', 'service_item_package_id', 'id', 'package_info')\
               .project({'_id': 0, 'item_list': '$package_info.service_item'})
        item_data_org = self.query(_filter, 'PT_Bed')
        if len(item_data_org) > 0:
            item_data = item_data_org[0]['item_list']
        else:
            item_data = []
        order_id = str(uuid.uuid1())
        order_data = {'service_provider_id': get_current_organization_id(self.session),
                      'purchaser_id': data['residents_id'],
                      'order_data': datetime.datetime.now(),
                      'service_item': item_data,
                      'status': OrderStatus.order_unserved.value,
                      'id': order_id}
        check_in_data = {'order_id': order_id, 'user_id': data['residents_id']}
        bill_id_add = self.bill_manage_server.add_bill(OperationType.add.value,
                                                       TypeId.accommodationRecord.value, [data, order_data, check_in_data], ['PT_Accommodation_Record', 'PT_Service_Order', 'IEC_Chect_In'])
        bill_id_update = self.bill_manage_server.add_bill(OperationType.update.value,
                                                          TypeId.bed.value, insert_bed, 'PT_Bed')
        if bill_id_add and bill_id_update:
            res = 'Success'
        return res

    def check_out_process(self, user_id):
        ''' 退住过程 包括
                （1）解绑床位 PT_Bed
                （2）更新旧床位的入住记录 PT_Accommodation_Record
                （3）更新住宿登记表 IEC_Chect_In
                （4）更新旧订单的状态 PT_Service_Order
                （5）对旧床位生成相应的服务记录 PT_Service_Record
        '''
        res = 'Fail'
        end_date = datetime.datetime.now()
        # (1)床位
        _filter = MongoBillFilter()
        _filter.match_bill(C('residents_id') == user_id)
        old_bed_data = self.query(_filter, 'PT_Bed')
        # print(old_bed_data,'old_bed_data>>>')
        # 旧床位数据
        old_bed_update_data = {}
        if len(old_bed_data) > 0:
            old_bed_update_data = {
                'id': old_bed_data[0]['id'], 'residents_id': ""}
        else:
            return '找不到长者的床位'

        # (2)入住记录
        _filter = MongoBillFilter()
        _filter.match_bill((C('residents_id') == user_id)
                           & (C('bed_id') == old_bed_data[0]['id'])
                           & (C('checkout_date') == None))\
            .sort({'checkin_date': -1})\
            .project({'_id': 0})
        accommodation_data = self.query(_filter, 'PT_Accommodation_Record')
        change_accommodation_data = {}
        if len(accommodation_data) > 0:
            change_accommodation_data = dict(
                accommodation_data[0], **{'checkout_date': end_date, 'outer_remark': '退住'})
        else:
            return '找不到该长者入住记录，是否请假还未回来？'
        res_date = self.create_accommodation_data(change_accommodation_data)
        # 旧床位请假记录
        old_accommodation_data = res_date['accommodation_data']
        # 旧床位核算的服务记录 （5）对旧床位生成相应的服务记录
        record_accommodation_data = res_date['record_item_datas']

        # (3)住宿登记
        _filter = MongoBillFilter()
        _filter.match_bill((C('user_id') == user_id) & (
            C('state') == CheckInStatus.check_in.value))
        check_in_org = self.query(_filter, 'IEC_Check_In')
        # 入住记录待更新数据
        check_in_data = {}
        # 旧订单待更新数据
        old_order_data = {}
        if len(check_in_org) > 0:
            check_in_data = {
                'id': check_in_org[0]['id'], 'state': CheckInStatus.retreat.value}
            # （4）更新旧订单的状态
            old_order_data = {
                'id': check_in_org[0]['order_id'], 'status': OrderStatus.order_completed.value}
        bill_add = self.bill_manage_server.add_bill(OperationType.add.value,
                                                    TypeId.accommodationRecord.value, [
                                                        record_accommodation_data],
                                                    ['PT_Service_Record'])
        bill_update = self.bill_manage_server.add_bill(OperationType.update.value,
                                                       TypeId.accommodationRecord.value, [
                                                           old_bed_update_data, old_accommodation_data, old_order_data, check_in_data],
                                                       ['PT_Bed', 'PT_Accommodation_Record', 'PT_Service_Order', 'IEC_Check_In'])
        if bill_add and bill_update:
            res = 'Success'
        return res
    # def back_after_leave_process(self, data):
    #     '''销假过程：包括生成入住记录
    #     Args :
    #     data：包括字段bed_id,checkin_date,enter_id,enter_operate_personnel_id,enter_record_reason_id,residents_id,enter_remark
    #     '''
    #     res = 'Fail'
    #     bill_id = self.bill_manage_server.add_bill(OperationType.add.value,
    #                                                TypeId.accommodationRecord.value, data, 'PT_Accommodation_Record')
    #     if bill_id:
    #         res = 'Success'
    #     return res

    def update_process_item_data(self, data):
        '''新增/更新表PT_Process_Item数据'''
        res = 'Fail'
        bill_id = self.bill_manage_server.add_bill(OperationType.add.value,
                                                   TypeId.accommodationRecord.value, data, 'PT_Process_Item')
        if bill_id:
            res = 'Success'
        return res

    def get_item_info(self, process_name, order_id, cal_values):
        '''获取生成记录所需的部分数据，包括：生成对应记录的item及其选项和计价公式
        Args :
        item_name:需要计算的过程名称（需要去映射表PT_Process_Item中找到对应过程的项目id）
        order_id:订单编号
        cal_values：计算订单金额时所需的值，字典类型
        '''
        # 1,拿对应的服务项目
        # 2，到订单中拿对应的服务项目的选项
        # 3，到服务项目中拿计算公式（修改后应该在订单中有计算公式，目前暂不是该写法）
        _filter = MongoBillFilter()
        _filter.match_bill(C('id') == order_id)\
               .unwind('detail')\
               .inner_join_bill('PT_Service_Product', 'detail.product_id', 'id', 'product') \
               .inner_join_bill('PT_Service_Item', 'product.service_item_id', 'id', 'item') \
               .add_fields({'process_name': process_name})\
               .inner_join('PT_Process_Item', 'item.id', 'item_id', 'process_item') \
               .match(C('process_item.process_name') == process_name) \
               .lookup_bill('PT_Service_Item', 'process_item.item_id', 'id', 'item_info') \
               .project({'detail': 1, 'product_id': '$product.id', 'id': 1})
        item_data = self.query(_filter, 'PT_Service_Order')
        res = []
        if len(item_data) > 0:
            for item in item_data:
                detail = item['detail']
                option_data = detail['service_option']  # 选项
                service_product_id = detail['product_id']  # 产品id
                valuation_formula = detail['valuation_formula'][0]['formula']
                for i in option_data:
                    if i['name'] in list(cal_values.keys()):
                        i['option_value'] = cal_values[i['name']]
                amount = round(execute_python(valuation_formula,
                                              option_data, 'name', 'option_value'), 2)  # 计价金额
                res.append({'order_id': order_id, 'service_product_id': service_product_id,
                            'valuation_amount': amount, 'service_option': option_data})
        else:
            raise JsonRpc2Error(-36111, '找不到长者订单或服务过程项目字段缺失')
        return res

    def _get_newest_checkin_date(self, residents_id):
        ''' 获取当前月份最早的入住时间
            Args:
                residents_id    长者id
            return:
                {'start_date':最早时间 }

        '''
        params = {}
        # 获取当前结束时间
        date = get_cur_time()
        month_date = get_first_last_day_month(date.year, date.month)
        params['start_date'] = get_string_to_date(month_date[0])
        # 查询本月是否存在住宿记录
        _filter = MongoBillFilter()
        _filter.match_bill((C('residents_id') == residents_id) & (C('checkin_date') >= params['start_date'])) \
            .sort({'checkin_date': -1})\
            .project({'_id': 0})
        res = self.query(
            _filter, 'PT_Accommodation_Record')
        if len(res):
            params['start_date'] = res[0]['checkin_date']
        return params

    # def ask_for_leave_process(self, data):
    #     '''请假过程：包括生成服务记录，更新入住记录
    #     Args :
    #     data：包括字段id,bed_id,checkout_date,outer_id,outer_operate_personnel_id,outer_record_reason_id,residents_id,outer_remark
    #     '''
    #     res = 'Fail'
    #     end_date = datetime.datetime.now()
    #     _filter = MongoBillFilter()
    #     _filter.match_bill(C('user_id') == data['residents_id'])
    #     tep_data = self.query(_filter, 'IEC_Check_In')
    #     if len(tep_data) > 0:
    #         order_id = tep_data[0]['order_id']
    #         record_start_date_dict = self._get_newest_checkin_date(
    #             data['residents_id'])
    #         days = (end_date-record_start_date_dict['start_date']).days+1
    #         record_item_data_dict = self.get_item_info(
    #             '住宿', order_id, {'天数': days})
    #         record_data = dict(record_start_date_dict, **record_item_data_dict)
    #         record_data = dict(record_data, **{'end_date': end_date, 'order_id': order_id,
    #                                            'status': RecordStatus.service_completed.value})
    #         bill_record = self.bill_manage_server.add_bill(OperationType.add.value,
    #                                                        TypeId.accommodationRecord.value, record_data, 'PT_Service_Record')
    #         bill_acc = self.bill_manage_server.add_bill(OperationType.update.value,
    #                                                     TypeId.accommodationRecord.value, data, 'PT_Accommodation_Record')
    #         if bill_record and bill_acc:
    #             res = 'Success'
    #     return res

    def change_room_process(self, data, noChangeBed):
        '''换房过程：包括
                    （1）解绑旧床位,绑定新床位 PT_Bed
                    （2）生成新床位的服务订单,更新旧订单的状态 PT_Service_Order
                    （3）生成新床位的入住记录，更新旧床位的入住记录 PT_Accommodation_Record
                    （4）更新住宿登记表 IEC_Chect_In
                    （5）对旧床位生成相应的服务记录 PT_Service_Record
            Args :
            data : 包括字段
            user_id,
            service_item,
            service_provider_id, // 获取服务提供者
            new_bed_id,
        '''
        res = 'Fail'
        # print(data['service_item'],'service_item>>>')
        end_date = datetime.datetime.now()
        # (1)床位
        _filter = MongoBillFilter()
        _filter.match_bill(C('residents_id') == data['user_id'])
        old_bed_data = self.query(_filter, 'PT_Bed')
        # print(old_bed_data,'old_bed_data>>>')
        # 旧床位数据
        old_bed_update_data = {}
        if len(old_bed_data) > 0:
            old_bed_update_data = {
                'id': old_bed_data[0]['id'], 'residents_id': ""}
        else:
            return '找不到长者的床位'
        # 新床位数据
        new_bed_update_data = {
            'id': data['new_bed_id'], 'residents_id': data['user_id']}

        # (2)服务订单
        _filter = MongoBillFilter()
        _filter.match_bill(C('id') == data['new_bed_id'])
        new_bed_data = self.query(_filter, 'PT_Bed')
        product_id = ''
        if len(new_bed_data) > 0:
            # 产品id
            product_id = new_bed_data[0]['service_item_package_id']
        else:
            return '找不到新床位信息'
        # 创建订单
        # per_data = {'count':1,'service_product_id':product_id}
        # order_res = self.confirm_order_func._create_product_order(per_data,0)
        # 新订单数据
        order_code = ''

        def process_func(db):
            nonlocal order_code
            order_code = get_serial_number(db, SerialNumberType.order.value)
        process_db(self.db_addr, self.db_port, self.db_name,
                   process_func, self.db_user, self.db_pwd)
        order_recode = {
            'purchaser_id': data['user_id'],
            'order_code': order_code,
            'service_provider_id': get_current_organization_id(self.session),
            'status': '未服务',
            'order_date': end_date,
            'service_date': end_date,
            'detail': data['detail'],
            'is_paying_first': '0'
        }
        # 生成订单
        new_order_data = get_info(order_recode, self.session)
        new_order_id = new_order_data['id']
        # (3)入住记录
        _filter = MongoBillFilter()
        _filter.match_bill((C('residents_id') == data['user_id'])
                           & (C('bed_id') == old_bed_data[0]['id'])
                           & (C('checkout_date') == None))\
            .sort({'checkin_date': -1})\
            .project({'_id': 0})
        accommodation_data = self.query(_filter, 'PT_Accommodation_Record')
        change_accommodation_data = {}
        if len(accommodation_data) > 0:
            change_accommodation_data = dict(
                accommodation_data[0], **{'checkout_date': end_date, 'outer_remark': '换房'})
        else:
            return '找不到该长者入住记录，是否请假还未回来？'
        res_date = self.create_accommodation_data(change_accommodation_data)
        # 旧床位请假记录
        old_accommodation_data = res_date['accommodation_data']
        old_accommodation_data['status'] = '离开'
        # 旧床位核算的服务记录
        record_accommodation_data = res_date['record_item_datas']
        # 新床位销假记录
        new_accommodation_data = {'bed_id': data['new_bed_id'], 'checkin_date': end_date, 'enter_operate_personnel_id': get_current_user_id(
            self.session), 'residents_id': data['user_id'], 'enter_remark': '换房', 'id': str(uuid.uuid1()), 'status': '入住', 'create_date': get_cur_time()}

        # (4)住宿登记
        _filter = MongoBillFilter()
        _filter.match_bill((C('user_id') == data['user_id']) & (
            C('state') == CheckInStatus.check_in.value))
        check_in_org = self.query(_filter, 'IEC_Check_In')
        # 入住记录待更新数据
        check_in_data = {}
        # 旧订单待更新数据
        old_order_data = {}
        if len(check_in_org) > 0:
            check_in_data = {'order_id': new_order_id,
                             'id': check_in_org[0]['id'], 'accommodation_id': new_accommodation_data['id']}
            old_order_data = {
                'id': check_in_org[0]['order_id'], 'status': OrderStatus.order_completed.value}

        update_data = [old_accommodation_data, old_order_data]
        update_table = ['PT_Accommodation_Record', 'PT_Service_Order']
        if noChangeBed:  # 不修改床位，只调整服务价格
            old_order_data['status'] = OrderStatus.order_going.value
            old_order_data['detail'] = data['detail']
            new_accommodation_data['bed_id'] = old_bed_update_data['id']
            old_bed_update_data = {}
            new_bed_update_data = {}
            new_order_data = {}
            check_in_data = {}
        else:
            update_data = update_data + \
                [old_bed_update_data, new_bed_update_data, check_in_data]
            update_table = update_table + ['PT_Bed', 'PT_Bed', 'IEC_Check_In']
        # raise '错误'
        bill_add = self.bill_manage_server.add_bill(OperationType.add.value,
                                                    TypeId.accommodationRecord.value, [
                                                        record_accommodation_data, new_accommodation_data, new_order_data],
                                                    ['PT_Service_Record', 'PT_Accommodation_Record', 'PT_Service_Order'])

        bill_update = self.bill_manage_server.add_bill(
            OperationType.update.value, TypeId.accommodationRecord.value, update_data, update_table)

        if bill_add and bill_update:
            res = 'Success'
        return res

    def create_accommodation_data(self, accommodation_data):
        ''' 
            更新入住记录的请假时间、虚拟请假时间,获取时间对象
            调用方：退住、调房、请假
            accommodation_data: 请假记录对象
            return ：{'入住记录的请假记录对象','服务项目记录对象数组'}
        '''
        day_res = {}
        start_date = datetime.datetime.now()
        end_date = datetime.datetime.now()
        # 1、判断虚拟出时间是否存在（测过）
        if 'fictitious_checkout_date' in accommodation_data.keys():
            # 存在
            # 实际天数
            checkout_date = accommodation_data['checkout_date']
            if isinstance(accommodation_data['checkout_date'], str):
                checkout_date = as_date(accommodation_data['checkout_date'])

            fictitious_checkout_date = accommodation_data['fictitious_checkout_date']
            if isinstance(accommodation_data['fictitious_checkout_date'], str):
                fictitious_checkout_date = as_date(
                    accommodation_data['fictitious_checkout_date'])

            actual_days = (checkout_date - fictitious_checkout_date).days
            # 请假天数
            leave_day = 0
            # 总天数
            total_day = actual_days
            day_res = {'实际发生天数': actual_days,
                       '请假天数': leave_day, '总天数': total_day}
            accommodation_data['fictitious_checkout_date'] = checkout_date
            start_date = fictitious_checkout_date
            end_date = checkout_date
            # print(day_res,'aaaaaaaaaaaaaaaaaaaaday_res：')
        else:
            # 不存在 (测过)
            accommodation_data['fictitious_checkout_date'] = accommodation_data['checkout_date']
            res_data = self.calculation_day(accommodation_data)
            # print(res_data, 'bbbbbbbbbbbbbbbbbbbbbbres_data>>>')
            start_date = res_data['start_date']
            end_date = res_data['end_date']
            day_res = res_data['day']
        record_item_datas = self.create_record(
            accommodation_data['residents_id'], start_date, end_date, day_res)
        # print('<><><><><>',record_item_datas,"<><><><><>")
        return {'accommodation_data': accommodation_data, 'record_item_datas': record_item_datas}

    def calculation_day(self, new_accommodation_data):
        '''
            new_accommodation_data 新产生的请假记录对象:{}
            根据入住记录计算实际发生天数、请假天数、总天数，
            return {'day':{'实际天数': actual_days,'请假天数':leave_day,'总天数':total_day},'start_date':'','end_date':''}
        '''
        # 1、根据住宿记录表的本次虚拟出时间减上次虚拟出时间,如没有上次虚拟出则减上次入时间
        # 上次入时间
        checkin_date = new_accommodation_data['checkin_date']
        if isinstance(new_accommodation_data['checkin_date'], str):
            checkin_date = as_date(new_accommodation_data['checkin_date'])
        # 本次虚拟出时间
        now_fictitious_checkout_date = new_accommodation_data['fictitious_checkout_date']
        if isinstance(new_accommodation_data['fictitious_checkout_date'], str):
            now_fictitious_checkout_date = as_date(
                new_accommodation_data['fictitious_checkout_date'])
        # 上次虚拟出时间,默认取上次入时间（测过）
        last_fictitious_checkout_date = checkin_date
        _filter = MongoBillFilter()
        _filter.match_bill((C('residents_id') == new_accommodation_data['residents_id'])
                           & (C('bed_id') == new_accommodation_data['bed_id'])) \
            .sort({'checkin_date': -1})\
            .project({'_id': 0})
        res = self.query(
            _filter, 'PT_Accommodation_Record')
        if len(res) > 1:
            # 上次虚拟出时间，取上次虚拟出时间（测过）
            last_fictitious_checkout_date = res[1]['fictitious_checkout_date']
            # print(last_fictitious_checkout_date,'last_fictitious_date>>>>>>')
        total_day = (now_fictitious_checkout_date -
                     last_fictitious_checkout_date).days
        actual_days = (now_fictitious_checkout_date - checkin_date).days
        leave_day = total_day - actual_days

        return {'day': {'实际发生天数': actual_days, '请假天数': leave_day, '总天数': total_day}, 'start_date': last_fictitious_checkout_date, 'end_date': now_fictitious_checkout_date}

    def create_record(self, user_id, start_date, end_date, day_res):
        '''
            生成服务记录的通用方法 
            user_id：核算的人员Id
            day_res：天数选项数据，字典类型
            return 服务记录的数组对象：[{}]
        '''
        # 1、通过人员id找到订单Id
        _filter = MongoBillFilter()
        _filter.match_bill(
            (C('user_id') == user_id) & (C('state') == CheckInStatus.check_in.value))
        check_in_org = self.query(_filter, 'IEC_Check_In')
        # print(day_res, 'day_res')
        service_recode_datas = []
        if len(check_in_org) > 0:
            # 2、查询对照表，找到需要核算所有服务产品,并构造服务记录对象
            record_item_datas = self.get_item_info(
                '请假', check_in_org[0]['order_id'], day_res)
            # 获取当前服务人员id
            servicer_id = get_current_user_id(self.session)
            date_recode = {'start_date': start_date, 'end_date': end_date,
                           'status': RecordStatus.service_completed.value, 'servicer_id': servicer_id}
            # print('《》《》《》《》《》',record_item_datas,"《》《》《》《》《》")
            if len(record_item_datas) > 0:
                for record_item in record_item_datas:
                    res_record_item_data = dict(record_item, **date_recode)
                    service_recode_data = self.service_operation_func.add_service_record(
                        res_record_item_data['order_id'], res_record_item_data['service_product_id'], '0', other=res_record_item_data)
                    service_recode_datas.append(service_recode_data)
                # print('cccccccccccccccc',service_recode_datas,'《》《》《》《》：service_recode_datas>>')
        return service_recode_datas

    def auto_creat_service_record(self):
        '''
            用于点击按钮生成所有人员至当前天的与请假/销假相关的服务记录
        '''
        res = 'Fail'
        # 1、获取所有在住人员列表
        _filter = MongoBillFilter()
        _filter.match_bill((C('state') == CheckInStatus.check_in.value))
        check_in_data = self.query(_filter, 'IEC_Check_In')
        # 2、生成服务记录
        if len(check_in_data) > 0:
            record_datas = []
            service_record_datas = []
            for check_in in check_in_data:
                # 2、计算请假/销假的时间
                actual_days = 0
                leave_day = 0
                total_day = 0
                start_date = datetime.datetime.now()
                end_date = datetime.datetime.now()
                # 当前时间
                now_date = datetime.datetime.now()
                # 2.1、判断已存在的住宿记录，长者是一直都在，还是一直都未回来
                _filter = MongoBillFilter()
                _filter.lookup_bill('PT_Bed', 'bed_id', 'id', 'bed')\
                    .match_bill((C('residents_id') == check_in['user_id']) & (C('bed.residents_id') == check_in['user_id']))\
                    .sort({'checkin_date': -1})\
                    .project({'_id': 0})
                record_res = self.query(_filter, 'PT_Accommodation_Record')
                if len(record_res) > 0:
                    if 'checkout_date' in record_res[0]:
                        # 还未回来（测过）
                        leave_day = (
                            now_date - record_res[0]['fictitious_checkout_date']).days
                        total_day = leave_day
                        start_date = record_res[0]['fictitious_checkout_date']
                        end_date = now_date
                    else:
                        # 长者一直都在
                        if len(record_res) > 1:
                            # 有上次虚拟出时间(测过)
                            actual_days = (
                                now_date - record_res[1]['fictitious_checkout_date']).days
                            total_day = actual_days
                            start_date = record_res[1]['fictitious_checkout_date']
                            end_date = now_date
                        else:
                            # 没有上次虚拟出时间，刚入住(测过)
                            actual_days = (
                                now_date - record_res[0]['checkin_date']).days
                            total_day = actual_days
                            start_date = record_res[0]['checkin_date']
                            end_date = now_date
                    record_res[0]['fictitious_checkout_date'] = now_date
                    record_datas.append(record_res[0])

                    day_res = {'实际发生天数': actual_days,
                               '请假天数': leave_day, '总天数': total_day}
                    service_record = self.create_record(
                        check_in['user_id'], start_date, end_date, day_res)
                    service_record_datas = service_record_datas + service_record
            if record_datas and service_record_datas:
                bill_update = self.bill_manage_server.add_bill(
                    OperationType.update.value, TypeId.btnCreateRecord.value, record_datas, ['PT_Accommodation_Record'])
                bill_add = self.bill_manage_server.add_bill(
                    OperationType.add.value, TypeId.btnCreateRecord.value, service_record_datas, ['PT_Service_Record'])
                if bill_add and bill_update:
                    res = 'Success'
        return res
